import requests
import json

import requests
import time
import requests
import json
from typing import Dict, List, Optional, Any

from lark_oapi import Client
from lark_oapi.api.bitable.v1 import *
from typing import Dict, List, Optional, Any

class FeishuBase:
    """飞书多维表格操作类"""

    def __init__(self, app_id: str, app_secret: str):
        """
        初始化飞书多维表格操作类

        :param app_id: 飞书开放平台应用ID
        :param app_secret: 飞书开放平台应用密钥
        """
        self.app_id = app_id
        self.app_secret = app_secret
        self.base_url = "https://open.feishu.cn/open-apis"
        self.token = self._get_access_token()

    def _get_access_token(self) -> str:
        """获取访问令牌"""
        url = f"{self.base_url}/auth/v3/tenant_access_token/internal"
        headers = {"Content-Type": "application/json"}
        data = {
            "app_id": self.app_id,
            "app_secret": self.app_secret
        }

        response = requests.post(url, headers=headers, json=data)
        response_data = response.json()

        if response_data.get("code") != 0:
            raise Exception(f"获取访问令牌失败: {response_data.get('msg')}")

        return response_data.get("tenant_access_token")

    def create_bitable(self, app_token: str, name: str, desc: str = "") -> Dict[str, Any]:
        """
        创建多维表格

        :param app_token: 应用token（通常是知识库的token）
        :param name: 多维表格名称
        :param desc: 多维表格描述
        :return: 创建的多维表格信息
        """
        url = f"{self.base_url}/bitable/v1/apps/{app_token}/tables"
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.token}"
        }

        data = {
            "name": name,
            "desc": desc
        }

        response = requests.post(url, headers=headers, json=data)
        response_data = response.json()

        if response_data.get("code") != 0:
            raise Exception(f"创建多维表格失败: {response_data.get('msg')}")

        return response_data.get("data", {})

    def get_bitable(self, app_token: str, table_id: str) -> Dict[str, Any]:
        """
        获取多维表格信息

        :param app_token: 应用token
        :param table_id: 表格ID
        :return: 多维表格信息
        """
        url = f"{self.base_url}/bitable/v1/apps/{app_token}/tables/{table_id}"
        headers = {
            "Authorization": f"Bearer {self.token}"
        }

        response = requests.get(url, headers=headers)
        response_data = response.json()

        if response_data.get("code") != 0:
            raise Exception(f"获取多维表格失败: {response_data.get('msg')}")

        return response_data.get("data", {})

    def list_bitable_tables(self, app_token: str) -> List[Dict[str, Any]]:
        """
        获取应用下的所有多维表格

        :param app_token: 应用token
        :return: 多维表格列表
        """
        url = f"{self.base_url}/bitable/v1/apps/{app_token}/tables"
        headers = {
            "Authorization": f"Bearer {self.token}"
        }

        response = requests.get(url, headers=headers)
        response_data = response.json()

        if response_data.get("code") != 0:
            raise Exception(f"获取多维表格列表失败: {response_data.get('msg')}")

        return response_data.get("data", {}).get("items", [])

    def create_table_record(self, app_token: str, table_id: str, fields: Dict[str, Any]) -> Dict[str, Any]:
        """
        在表格最上方增加新的行数据

        :param app_token: 应用token
        :param table_id: 表格ID
        :param fields: 行数据字段，格式为{字段名: 值}
        :return: 创建的行记录信息
        """
        url = f"{self.base_url}/bitable/v1/apps/{app_token}/tables/{table_id}/records"
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.token}"
        }

        # 构建请求数据，使用insert_before表示插入到最上方
        data = {
            "records": [
                {
                    "fields": fields,
                    "insert_before": ""  # 空字符串表示插入到最前面
                }
            ]
        }

        response = requests.post(url, headers=headers, json=data)
        response_data = response.json()

        if response_data.get("code") != 0:
            raise Exception(f"创建表格记录失败: {response_data.get('msg')}")

        return response_data.get("data", {})

    def get_table_records(self, app_token: str, table_id: str, page_size: int = 100) -> List[Dict[str, Any]]:
        """
        获取表格中的记录

        :param app_token: 应用token
        :param table_id: 表格ID
        :param page_size: 每页记录数
        :return: 记录列表
        """
        all_records = []
        page_token = ""

        while True:
            url = f"{self.base_url}/bitable/v1/apps/{app_token}/tables/{table_id}/records"
            headers = {
                "Authorization": f"Bearer {self.token}"
            }

            params = {
                "page_size": page_size,
                "page_token": page_token
            }

            response = requests.get(url, headers=headers, params=params)
            response_data = response.json()

            if response_data.get("code") != 0:
                raise Exception(f"获取表格记录失败: {response_data.get('msg')}")

            data = response_data.get("data", {})
            all_records.extend(data.get("items", []))

            page_token = data.get("page_token")
            if not page_token:
                break

        return all_records


class FeishuBitable:
    def __init__(self, app_id, app_secret, app_token=None):
        """
        初始化飞书多维表格操作对象
        :param app_id: 飞书应用ID
        :param app_secret: 飞书应用密钥
        :param app_token: 多维表格ID（可选）
        """
        self.app_id = app_id
        self.app_secret = app_secret
        self.app_token = app_token
        self.base_url = "https://open.feishu.cn/open-apis"#https://open.feishu.cn/open-apis/bitable/v1/apps
        self.access_token = None
        self.token_expire = 0
        # self._get_access_token()

    def _get_access_token(self):
        """获取并缓存飞书访问令牌"""
        if time.time() < self.token_expire - 60:  # 提前60秒刷新
            return self.access_token

        url = f"{self.base_url}/auth/v3/tenant_access_token/internal"
        headers = {"Content-Type": "application/json"}
        payload = {
            "app_id": self.app_id,
            "app_secret": self.app_secret
        }

        response = requests.post(url, headers=headers, json=payload)
        result = response.json()

        if response.status_code != 200 or result.get("code") != 0:
            raise Exception(f"获取access_token失败: {result}")

        self.access_token = result["tenant_access_token"]
        self.token_expire = time.time() + result["expire"]
        return self.access_token

    def _request(self, method, endpoint, app_token=None, **kwargs):
        """发送API请求"""
        token = self._get_access_token()
        headers = {
            "Authorization": f"Bearer {token}",
            "Content-Type": "application/json"
        }

        # 处理多维表格ID
        current_app_token = app_token or self.app_token
        if not current_app_token:
            raise ValueError("缺少app_token参数")

        # 替换路径中的占位符
        endpoint = endpoint.replace("{app_token}", current_app_token)
        url = f"{self.base_url}{endpoint}"

        response = requests.request(method, url, headers=headers, **kwargs)
        if response.status_code >= 400:
            raise Exception(f"API请求失败: {response.status_code} - {response.text}")
        return response.json()

    def create_base(self, folder_token, name):
        """
        创建多维表格
        :param folder_token: 云文档文件夹token
        :param name: 多维表格名称
        :return: 新创建的多维表格信息
        """
        endpoint = "/bitable/v1/apps"
        payload = {
            "folder_token": folder_token,
            "name": name
        }
        result = self._request("POST", endpoint, json=payload)
        return result.get("data", {}).get("app", {})

    def get_base(self, app_token=None):
        """
        获取多维表格信息
        :param app_token: 多维表格ID（可选）
        :return: 多维表格详细信息
        """
        endpoint = "/bitable/v1/apps/{app_token}"
        result = self._request("GET", endpoint, app_token=app_token)
        return result.get("data", {}).get("app", {})

    def create_table(self, table_name, fields=None, app_token=None):
        """
        创建数据表
        :param table_name: 表名称
        :param fields: 字段定义（可选）
        :param app_token: 多维表格ID（可选）
        :return: 新创建的表信息
        """
        endpoint = "/bitable/v1/apps/{app_token}/tables"
        payload = {"name": table_name}
        if fields:
            payload["fields"] = fields

        result = self._request("POST", endpoint, json=payload, app_token=app_token)
        return result.get("data", {}).get("table", {})

    def get_tables(self, app_token=None):
        """
        获取所有表信息
        :param app_token: 多维表格ID（可选）
        :return: 表信息列表
        """
        endpoint = "/bitable/v1/apps/{app_token}/tables"
        result = self._request("GET", endpoint, app_token=app_token)
        return result.get("data", {}).get("items", [])

    def add_records(self,table_id, records, app_token=None):
        """
        在表顶部添加新行
        :param table_id: 表ID
        :param records: 要添加的记录列表
        :param app_token: 多维表格ID（可选）
        :return: 新创建的记录ID列表
        """
        endpoint = f"/bitable/v1/apps/{{app_token}}/tables/{table_id}/records/batch_create"

        # 构建记录数据
        records_data = [{"fields": record} for record in records]
        payload = {"records": records_data}

        result = self._request("POST", endpoint, json=payload, app_token=app_token)
        rst=[rec["record_id"] for rec in result.get("data", {}).get("records", [])]
        if not rst:
            print(result)
        return rst

    def set_app_token(self, app_token):
        """设置默认的多维表格ID"""
        self.app_token = app_token



